<script setup lang="ts">
import dayjs from 'dayjs'
import useFileToArraybuffer from '@/hooks/useFileToArraybuffer'
import useEpubCover from '@/hooks/epub/useEpubCover'
import usePdfCover from '@/hooks/pdfjs/usePdfCover'
import useZipCover, { type zipCoverType } from '@/hooks/zip/useZipCover'

import type { UploadFileInfo } from 'naive-ui'
import { ref } from 'vue'
import { useDialog, useMessage } from 'naive-ui'
import { db, type Book as BookDB } from '@/db/db'
import { ReloadCircleSharp, ArchiveOutline as ArchiveIcon } from '@vicons/ionicons5'
import { DOC_FORMAT } from '@/constant/documentFormat'

const emits = defineEmits(['finish'])
const loading = ref(false)
const message = useMessage()
const fileList = ref<UploadFileInfo[]>([])
const dialog = useDialog()

const showModal = ref(false)
const modalShow = () => (showModal.value = true)

const onChange = async (option: { file: UploadFileInfo; fileList: UploadFileInfo[] }) => {
  fileList.value.push(option.file)
}

const addIndexedDB = async (file: UploadFileInfo) => {
  try {
    let base64 = ''
    let password = ''
    const fileData = file.file as File
    const arrayBuffer = await useFileToArraybuffer(fileData)

    console.log('🚀 ~ addIndexedDB ~ file.type:', file.type)
    switch (file.type) {
      case DOC_FORMAT.EPUB:
        base64 = await useEpubCover(arrayBuffer)
        break
      case DOC_FORMAT.PDF:
        base64 = await usePdfCover(arrayBuffer)
        break
      case DOC_FORMAT.ZIP:
      case DOC_FORMAT.XZIP:
        const tmpRes: zipCoverType = await useZipCover(fileData, file.name, dialog, message)
        base64 = tmpRes.img
        if (tmpRes.password) password = tmpRes.password
        break

      default:
        message.error('不支持该格式')
        throw new Error('不支持该格式')
    }

    const books = {
      id: file.id,
      name: file.name,
      type: file.type || null,
      file: file.file,
      cover: base64 || '',
      createTime: dayjs().valueOf(),
      lastTime: 0,
      currentIndex: 0,
    } as BookDB
    if (password) books.password = password

    const id = await db.books.add(books)
    console.log(`Added books, with ids: ${id}`)
    message.success(books.name + ' 保存成功')
  } catch (error) {
    message.error(file.name + ' 保存失败' + error)
    console.log('DB写入失败 :>> ', error)
  }
}
const onUpload = () => {
  loading.value = true

  const promises = fileList.value.map((i) => addIndexedDB(i))
  Promise.all(promises).finally(() => {
    emits('finish')

    loading.value = false
    fileList.value = []
    showModal.value = false
  })
}

defineExpose({ modalShow })
</script>

<template>
  <n-modal v-model:show="showModal" :mask-closable="false" to="#uploadModalTo">
    <n-card style="width: 600px" title="上传" :bordered="false" size="huge" role="dialog" aria-modal="true">
      <n-spin :show="loading" size="large" description="保存中，请稍等 。0_0 。">
        <template v-slot:icon>
          <n-icon><ReloadCircleSharp /></n-icon>
        </template>
        <n-upload
          multiple
          directory-dnd
          :default-upload="false"
          :max="10"
          accept=".epub,.pdf,.zip"
          :file-list="fileList"
          @change="onChange"
        >
          <n-upload-dragger>
            <div style="margin-bottom: 12px">
              <n-icon size="48" :depth="3">
                <ArchiveIcon />
              </n-icon>
            </div>
            <n-text style="font-size: 16px"> 点击或者拖动文件到该区域来上传 </n-text>
            <n-p depth="3" style="margin: 8px 0 0 0"> 支持格式：epub、zip图包、pdf </n-p>
          </n-upload-dragger>
        </n-upload>
        <n-flex justify="flex-end" style="margin-top: 30px">
          <n-button @click="showModal = false"> 关闭 </n-button>
          <n-button v-if="fileList.length" @click="onUpload"> 确定上传 </n-button>
        </n-flex>
      </n-spin>
    </n-card>
  </n-modal>
</template>

<style scoped></style>
